#pragma once
#include <commdlg.h>
#include <vector>
#include <dlgs.h>

enum SearchKind {
	kBytesFromHexDigits = 0,
	kUtf8,
	kUtf16LE,
	kUtf16BE,
	kTotalCount
};

static const UINT kWmMessageFindSettingsAreChanged = WM_APP + 10;


typedef std::vector<BYTE> ByteVector;
typedef std::vector<ByteVector> WhatCharactersVector;

class FindTextDialog
{
	HWND mFindDialogWindow;
	UINT mFindDialogMessage;
	HINSTANCE mInstance;
	FINDREPLACE mFindReplaceStruct;
	static const int kFindWhatLength = 80;
	TCHAR mFindWhat[kFindWhatLength];
	int mSearchKind;

	WhatCharactersVector mWhatVector;

	int mCurrentFindWhatLength;
	typedef std::vector<char32_t> Char32Vector;
	typedef std::vector<std::u32string> What32Vector;

public:
	FindTextDialog();
	~FindTextDialog();

	void SetInstance(HINSTANCE);
	void SetParentWindow(HWND);

	void ReopenDialog(SearchKind);
	void CloseDialog();
	int GetWmMessageId() const;
	void NullifyDialogHandle();
	bool IsProcessedDlgMessage(MSG* msg);

	void DisplayStatus(LPCTSTR);

	// if enable == false, the "Find Next" button is disabled;
	// if enable == true, the "Find Next" button state is determined by other
	// controls of the dialog. (for example, "Find What" field should be not empty)
	void EnableTheFindNextButton(bool enable);

	const WhatCharactersVector& GetWhat(FINDREPLACE*);
	bool IsSearchingDown() const;


	void OnStringChange();
private:
	LPCTSTR GetExtraDescription() const;
	bool MakeBytesFromHexDigits();
	std::u32string GetWhatText32();

	void SplitByCase(const std::u32string&, What32Vector& outVector);
	void OutputToBuffer(char32_t inChar, ByteVector& outBuffer);
	void CopyBytesTo(ByteVector& outVector, bool isLow) const;
	void ShowBytes(const ByteVector&, int contolId);
};

